﻿using System;
using System.Diagnostics;
using SfsTools.Core;
using mindvnas.Common;

namespace SfsTools.RmDir
{
    /// <summary>
    /// Implements the <em>rmdir</em> application.
    /// </summary>
    public class Program : ConsoleBase
    {
        #region Properties

        /// <summary>
        /// Contains the path to the image file to open.
        /// </summary>
        private String FImageFile;
        /// <summary>
        /// Contains the virtual path to remove.
        /// </summary>
        private String FVirtualPath;
        /// <summary>
        /// Controls whether to remove subdirectories and files as well.
        /// </summary>
        private bool FRecurse;

        #endregion

        #region Methods

        #region Entry point
        /// <summary>
        /// Entry point.
        /// </summary>
        /// <param name="arguments"></param>
        [DebuggerStepThrough]
        static void Main(String[] arguments)
        {
            new Program().Process(arguments);
        }
        #endregion

        #region Arguments

        /// <summary>
        /// Invoked before processing arguments.
        /// </summary>
        protected override void OnBeforeProcessArguments()
        {
            //FVirtualPath = null;
        }

        /// <summary>
        /// Invoked after processing arguments.
        /// </summary>
        protected override void OnAfterProcessArguments()
        {
            if (FVirtualPath != null)
            {
                // If not an absolute path, assume it is an absolue path.
                if (!FVirtualPath.StartsWith(new String(System.IO.Path.DirectorySeparatorChar, 1)))
                    FVirtualPath = String.Concat(System.IO.Path.DirectorySeparatorChar, FVirtualPath);
            }
        }

        /// <summary>
        /// Processes the specified command-line argument.
        /// </summary>
        /// <param name="argument">The command-line argument.</param>
        protected override void ProcessArgument(ConsoleBaseArgument argument)
        {
            if (argument.Name == "-image")
            {
                FImageFile = argument.Value;
                Arguments.Add(argument);
            }
            else if (argument.Name == "-path")
            {
                FVirtualPath = argument.Value;
            }
            else if (argument.Name == "-r")
            {
                FRecurse = true;
            }
            else
            {
                base.ProcessArgument(argument);
            }
        }

        /// <summary>
        /// Displays an usage notice.
        /// </summary>
        [DebuggerStepThrough]
        protected override void UsageParameters()
        {
            base.UsageParameters();
            //
            UsageParameter("-image", Translation.Resources.GetString("ArgI"));
            UsageParameter("-path", Translation.Resources.GetString("ArgP"));
            UsageParameter("-r", Translation.Resources.GetString("ArgR"));
        }

        #endregion

        /// <summary>
        /// Performs whatever the application does.
        /// </summary>
        protected override void ProcessCore()
        {
#if DEBUG
            String pathToVolume = @"E:\Work\VisualStudio\SfsTools\Core\";
            FImageFile = pathToVolume + "disk";
#endif
            if (HelpRequested || FImageFile == null || FVirtualPath == null)
            {
                HelpRequested = true;
                base.ProcessCore();
            }
            else
            {
                using (FileBackedVolume volume = FileBackedVolume.Open(FImageFile))
                {
                    using (TransactionalVolume trv = new TransactionalVolume(volume))
                    {
                        using (FileSystem fs = new FileSystem(trv))
                        {
                            // Get root directory.
                            IDirectory root = fs.RootDirectory;
                            IFileSystemObject fso = root.Resolve(FVirtualPath);
                            IDirectory dir = fso as IDirectory;
                            if (dir != null)
                            {
                                dir.Delete(FRecurse);
                            }
                            else
                            {
                                throw new PathDoesNotSpecifyDirectoryException();
                            }
                            // Commit changes.
                            trv.Commit();
                        }
                    }
                }
#if DEBUG
                Console.ReadLine();
#endif
            }
        }

        #endregion

        #region Constructors
        /// <overloads>Initializes a new instance of <see cref="Program"/>.</overloads>
        /// <summary>
        /// Initializes a new instance of <see cref="Program"/>.
        /// </summary>
        [DebuggerStepThrough]
        public Program()
            : base()
        {
        }
        #endregion
    }
}
